#include "daemonproxy.h"
#include <QDataStream>
#include <QDebug>
#include <QTimer>

#include "osdeamonservice.h"

#define SOCKET_NAME "os_daemon"

DaemonProxy::DaemonProxy(QObject *parent)
    : QObject{parent}
{
    initMap();
}

bool DaemonProxy::socketServer()
{
    m_localServer = new QLocalServer(this);
    QLocalServer::removeServer(SOCKET_NAME);
    connect(m_localServer,&QLocalServer::newConnection,this,&DaemonProxy::onNewConnction);
    return m_localServer->listen(SOCKET_NAME);
    
    m_localServer->close();
}

void DaemonProxy::onNewConnction()
{
    qDebug()<<"> onNewConnction() There is a new connection!";
    QLocalSocket *socket = nullptr;
    do{
        socket = m_localServer->nextPendingConnection();
        if(socket){
            connect(socket, &QLocalSocket::readyRead, this, &DaemonProxy::onReadyRead);
            connect(socket, &QLocalSocket::errorOccurred,this,[](QLocalSocket::LocalSocketError socketError){
                qDebug() << "> QLocalSocket() error:" << socketError;
            });
            connect(socket, &QLocalSocket::disconnected, socket, &QLocalSocket::deleteLater);
        }
    }while(socket);
    return;
}

void DaemonProxy::onReadyRead()
{
    QLocalSocket* socket = qobject_cast<QLocalSocket*>(sender());
    if(!socket)
        return;
    QDataStream input(socket);
    
    QString message;
    input >> message;
    
    qDebug() << __FUNCTION__ << "{ " << message << " }" ;
    
    switch(getEnumValue(message)){
    // os_personal
    case SocketObj::SO_Check:{
        qDebug() << "Message received: check";
        m_userCheck = true;
        m_commMap.insert(ProcessObj::PO_PersonCenter,socket);
        emit sigPostOtaFirmwareGet();
    }
    break;
    case SocketObj::SO_Autoupdate:{
        qDebug() << "Message received: autoupdate";
        QString autoStr;
        input >> autoStr;
        m_autoUpgrade = (autoStr == "true");
        qDebug() << "Message autoStr:" << autoStr;
        qDebug() << "Message autoUpgrade:" << m_autoUpgrade;
    }
    break;
    // os_ota
    case SocketObj::SO_OSUpgrade:{
        qDebug() << "Message received: OS_Upgrade";
        m_userCheck = false;
        m_commMap.insert(ProcessObj::PO_Upgrade,socket);
        emit sigReadTaskFile();
    }
    break;
    case SocketObj::SO_DoUpgradeSig:{
        qDebug() << "Message received: doUpgradeSig";
        emit sigDoUpgrade();
    }
    break;
    case SocketObj::SO_Tipstop:{
        qDebug() << "Message received: tipstop";
        emit sigTipStatus(2);
    }
    break;
    case SocketObj::SO_Tipstart:{
        qDebug() << "Message received: tipstart";
        emit sigTipStatus(0);
    }
    break;
    case SocketObj::SO_Shutdown:{
        qDebug() << "Message received: shutdown";
        QString error;
        input>>error;
        m_errorReShut = (error == "error");
        m_shutdown = true;
        m_reboot = false;
        emit sigPower();
    }
    break;
    case SocketObj::SO_reboot:{
        qDebug() << "Message received: reboot";
        QString error;
        input>>error;
        m_errorReShut = (error == "error");
        m_shutdown = false;
        m_reboot = true;
        emit sigPower();
    }
    break;
    case SocketObj::SO_Register:{
        qDebug() << "Message received: register";       // 注册失败，由sddm端发起的重新注册
        m_commMap.insert(ProcessObj::PO_SDDM,socket);
        emit sigSDDMRegister();
    }
    break;
    case SocketObj::SO_Wallpaper:{
        qDebug() << "Message received: GetWallpaper";
        QString user;
        input >> user;
        m_commMap.insert(ProcessObj::PO_Upgrade,socket);
        emit sigReadWallpaper(user);
    }
    break;
    case SocketObj::SO_EsportBox:{
        qDebug() << "Message received: esCheck";
        m_userCheck = true;
        m_commMap.insert(ProcessObj::PO_EsportBox,socket);
        emit sigPostOtaFirmwareGet();
    }break;
    default:{
        // log message
        qDebug() << "Message Unknown message" << message;
    }
    }//end of switch
    return;
}

void DaemonProxy::onSendMsg(ProcessObj pobj, QString msg)
{
    qDebug()<<"> DaemonProxy::onSendMsg() send message:"<<msg;
    if (m_commMap.contains(pobj) && m_commMap.value(pobj)) {
        QByteArray data;
        QDataStream output(&data, QIODevice::WriteOnly);
        QLocalSocket* socket = m_commMap.value(pobj);
        
        QStringList list = msg.split("@&@");
        for (const auto& v : list) {
            output << v;
        }
        
        if (socket->write(data) == -1) {
            qDebug() << "> DaemonProxy::onSendMsg() Failed to write data to socket:" << socket->errorString();
        } else if (!socket->flush()) {
            qDebug() << "> DaemonProxy::onSendMsg() Failed to flush socket:" << socket->errorString();
        }
    } else {
        qDebug() << "> DaemonProxy::onSendMsg() Message socket object error or not exist";
    }
}

void DaemonProxy::onDisconnectAllClient()
{
    QList<QLocalSocket*> clients = m_localServer->findChildren<QLocalSocket*>();
    for (QLocalSocket* client : clients) {
        if (client->state() == QLocalSocket::ConnectedState) {
            client->disconnectFromServer();
        }
    }
    m_commMap.clear();
}

void DaemonProxy::initMap()
{
    m_keywordMap.insert(SocketObj::SO_Check,            "check");
    m_keywordMap.insert(SocketObj::SO_Autoupdate,       "autoupdate");
    m_keywordMap.insert(SocketObj::SO_OSUpgrade,        "OS_Upgrade");
    m_keywordMap.insert(SocketObj::SO_DoUpgradeSig,     "doUpgradeSig");
    m_keywordMap.insert(SocketObj::SO_Tipstop,          "tipstop");
    m_keywordMap.insert(SocketObj::SO_Tipstart,         "tipstart");
    m_keywordMap.insert(SocketObj::SO_Shutdown,         "shutdown");
    m_keywordMap.insert(SocketObj::SO_reboot,           "reboot");
    m_keywordMap.insert(SocketObj::SO_Register,         "register");
    m_keywordMap.insert(SocketObj::SO_Wallpaper,        "GetWallpaper");
    //new add
    m_keywordMap.insert(SocketObj::SO_EsportBox,        "esCheck");
}
bool DaemonProxy::shutdown() const
{
    return m_shutdown;
}

bool DaemonProxy::userCheck() const
{
    return m_userCheck;
}

bool DaemonProxy::errorReShut() const
{
    return m_errorReShut;
}

bool DaemonProxy::reboot() const
{
    return m_reboot;
}
QString DaemonProxy::getKeyword(SocketObj socketObj)
{
    return m_keywordMap.value(socketObj);
}

DaemonProxy::SocketObj DaemonProxy::getEnumValue(QString keyword)
{
    return m_keywordMap.key(keyword,SocketObj::SO_Unkown);
}

bool DaemonProxy::autoUpgrade() const
{
    return m_autoUpgrade;
}

void DaemonProxy::setAutoUpgrade(bool newAutoUpgrade)
{
    m_autoUpgrade = newAutoUpgrade;
}
